﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Text;

namespace Weazel.Toad.Application.Actions
{
	/// <summary>
	/// Class representing a recent file. Recent files are stored 
	/// as an array of intances of this class in the settings registry.
	/// </summary>
	[Serializable]
	public class RecentFile
	{
		private string filename;
		public string Filename
		{
			get { return filename; }
			set { filename = value; }
		}

		private string fileType;
		public string FileType
		{
			get { return fileType; }
			set { fileType = value; }
		}

		public RecentFile()
		{
		}

		public RecentFile(string filename, string fileType)
		{
			this.Filename = filename;
			this.FileType = fileType;
		}

		/// <summary>
		/// Open this recent file.
		/// </summary>
		public void Open()
		{
			FileInfo file = new FileInfo(Filename);

			switch (FileType)
			{
				case "Vhdl":
					Items.VhdlTextFile vhdlFile = new Weazel.Toad.Application.Items.VhdlTextFile();
					vhdlFile.Filename = Filename;
					vhdlFile.DisplayName = file.Name;
					vhdlFile.Open();
					break;

				case "Gezel":
					Items.GezelTextFile gezelFile = new Weazel.Toad.Application.Items.GezelTextFile();
					gezelFile.Filename = Filename;
					gezelFile.DisplayName = file.Name;
					gezelFile.Open();					
					break;

				default:
					Items.TextFile textFile = new Weazel.Toad.Application.Items.TextFile();
					textFile.Filename = Filename;
					textFile.DisplayName = file.Name;
					textFile.Open();
					break;
			}
		}
	}

	/// <summary>
	/// Class representing a recent file in the GUI
	/// </summary>
	class RecentFileToolStripMenuItem : System.Windows.Forms.ToolStripMenuItem
	{
		private RecentFile recentFile;

		public RecentFileToolStripMenuItem(RecentFile recentFile)
		{
			this.recentFile = recentFile;
			this.Text = recentFile.Filename;
		}

		protected override void OnClick(EventArgs e)
		{
			recentFile.Open();
		}
	}

	class OpenRecentFileAction : ActionBase
	{
		private List<RecentFile> recentFiles;
		private int maxRecentFiles = 5;

		public OpenRecentFileAction()
		{
			recentFiles = new List<RecentFile>();
			loadFromSettings();

			// register handler for the ItemOpened event
			Application.Instance.ItemOpened += new EventHandler<ItemOpenedOrClosedEventArgs>(Instance_ItemOpened);

			// register handler for the ItemClosed event
			Application.Instance.ItemClosed += new EventHandler<ItemOpenedOrClosedEventArgs>(Instance_ItemClosed);
		}

		void Instance_ItemOpened(object sender, ItemOpenedOrClosedEventArgs e)
		{
			foreach (RecentFile recentFile in recentFiles)
				if (recentFile.Filename == e.Item.Filename)
				{
					recentFiles.Remove(recentFile);
					break;
				}

			update();
			saveToSettings();
		}

		void Instance_ItemClosed(object sender, ItemOpenedOrClosedEventArgs e)
		{
			string fileType =
				e.Item is Items.VhdlTextFile ? "Vhdl" :
				e.Item is Items.GezelTextFile ? "Gezel" :
				"text";

			if (recentFiles.Count >= maxRecentFiles)
				for (int i = recentFiles.Count - 1; i >= maxRecentFiles; i--)
					recentFiles.RemoveAt(i);

			recentFiles.Add(new RecentFile(e.Item.Filename, fileType));			
			update();
			saveToSettings();
		}

		private void saveToSettings()
		{
			Weazel.Toad.Application.Configuration.Settings.Default["RecentFiles"] = recentFiles.ToArray();
			Weazel.Toad.Application.Configuration.Settings.Default.Save();
		}

		private void loadFromSettings()
		{
			RecentFile[] files = Weazel.Toad.Application.Configuration.Settings.Default.RecentFiles;
	
			if (files != null)
			{
				foreach (RecentFile file in files)
					recentFiles.Add(file);
			}
		}

		private void updateItem(System.Windows.Forms.ToolStripItem item)
		{
			if (item is System.Windows.Forms.ToolStripMenuItem)
			{
				System.Windows.Forms.ToolStripMenuItem menuItem =
					item as System.Windows.Forms.ToolStripMenuItem;

				menuItem.DropDownItems.Clear();

				foreach (RecentFile recentFile in recentFiles)
					menuItem.DropDownItems.Add(new RecentFileToolStripMenuItem(recentFile));			 
			}
			else
			{
				throw new NotSupportedException("Recent files action can only be bound to ToolStipMenuItems");
			}
		}

		protected override void OnItemBound(System.Windows.Forms.ToolStripItem item)
		{
			updateItem(item);
		}

		private void update()
		{
			foreach (System.Windows.Forms.ToolStripItem item in boundItems)
				updateItem(item);
		}

		public override void Execute(object sender, EventArgs e)
		{		
			// intentionally left empty
		}
	}
}
